package cn.honqun.tinycms.service;

import cn.honqun.tinycms.FileObjectNotFoundException;
import cn.honqun.tinycms.domain.entity.FileObject;
import cn.honqun.tinycms.prop.FileObjectProperties;
import cn.honqun.tinycms.repository.FileObjectMapper;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 提供基础的文件对象服务
 */
public abstract class AbstractFileObjectService implements FileObjectService {
    protected static final String CACHE_NAME = "file_objects";

    protected FileObjectMapper fileObjectMapper;
    protected FileObjectProperties fileObjectProperties;
    protected RedissonClient redissonClient;

    /**
     * 根据URL,或者URI查询
     */
    protected FileObject selectByKey(String key) {
        Assert.notNull(key);

        FileObject fileObject;
        String uri = getCacheURI(key); //缓存key

        if (getCache().containsKey(uri)) {
            fileObject = getCache().get(uri);
        } else {
            fileObject = fileObjectMapper.selectByURI(uri);
            getCache().put(uri, fileObject, 24, TimeUnit.HOURS); //缓存24小时
        }

        return fileObject;
    }

    protected RMapCache<String, FileObject> getCache() {
        return redissonClient.getMapCache(CACHE_NAME);
    }

    protected String getCacheURI(String uriOrUrl) {
        if (StrUtil.startWith(uriOrUrl, fileObjectProperties.getHost())) { //如果是URL
            uriOrUrl = uriOrUrl.substring(fileObjectProperties.getHost().length()); //去掉域名部分，得到URI
        }
        return uriOrUrl;
    }

    @Override
    public FileObject selectByURL(String url) {
        return selectByKey(url);
    }

    @Override
    public FileObject selectByURI(String uri) {
        return selectByKey(uri);
    }

    @Override
    public void attach(String url, Long targetId) {
        FileObject fileObject = selectByKey(url);
        if (fileObject == null) {
            throw new FileObjectNotFoundException();
        }

        fileObject.setTargetId(targetId);
        fileObjectMapper.attach(fileObject);
    }

    @Override
    public void detach(String url) {
        FileObject fileObject = selectByKey(url);
        if (fileObject == null) {
            throw new FileObjectNotFoundException();
        }

        fileObject.setTargetId(null);
        fileObjectMapper.detach(fileObject);
    }

    @Override
    public List<FileObject> selectByTarget(Long targetId) {
        return fileObjectMapper.selectByTarget(targetId);
    }

    @Autowired
    public void setFileObjectMapper(FileObjectMapper fileObjectMapper) {
        this.fileObjectMapper = fileObjectMapper;
    }

    @Autowired
    public void setRedissonClient(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }

    @Autowired
    public void setFileObjectProperties(FileObjectProperties fileObjectProperties) {
        this.fileObjectProperties = fileObjectProperties;
    }
}
